﻿using Engine;
using Engine.Cameras;
using Engine.Terrain;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EngineDrawer.Terrain
{
    public class TerrainDrawer:DrawableGameComponent
    {
        #region Constructors

        public TerrainDrawer(Game game):base(game)
        {
        }

        #endregion

        #region Private fields

        private Effect _terrainEffect;        
        private VertexBuffer _vertexBuffer;        
        private IndexBuffer _indexBuffer;

        #endregion

        #region Properties

        public World World { get { return (World) Game.Services.GetService(typeof (World)); } }

        #endregion

        #region Override

        protected override void LoadContent()
        {
            _terrainEffect = Game.Content.Load<Effect>("effects\\terrain");
            var vertexDeclaration = new VertexDeclaration(VertexPositionTexture2Normal.VertexElements);            
            InitVertexAndIndexBuffers(vertexDeclaration);
            base.LoadContent();
        }
        public override void Draw(GameTime gameTime)
        {            
            Game.GraphicsDevice.Indices = _indexBuffer;
            Game.GraphicsDevice.SetVertexBuffer(_vertexBuffer);

            _terrainEffect.Parameters["SpecularColor"].SetValue(new Vector3(0.6f, 0.4f, 0.2f));
            _terrainEffect.Parameters["SpecularPower"].SetValue(8);
            _terrainEffect.Parameters["DiffuseColor"].SetValue(new Vector3(1, 1, 1));
            _terrainEffect.Parameters["AmbientLightColor"].SetValue(new Vector3(0.05333332f, 0.09882354f, 0.1819608f));
            _terrainEffect.Parameters["DirLight0Direction"].SetValue(new Vector3(-0.5265408f, -0.5735765f, -0.6275069f));
            _terrainEffect.Parameters["DirLight0DiffuseColor"].SetValue(new Vector3(1f, 0.9607844f, 0.8078432f));
            _terrainEffect.Parameters["DirLight0SpecularColor"].SetValue(new Vector3(1f, 0.9607844f, 0.8078432f));
            _terrainEffect.Parameters["DirLight1Direction"].SetValue(new Vector3(0.7198464f, 0.3420201f, 0.6040227f));
            _terrainEffect.Parameters["DirLight2Direction"].SetValue(new Vector3(0.4545195f, -0.7660444f, 0.4545195f));            
            _terrainEffect.Parameters["DirLight2DiffuseColor"].SetValue(new Vector3(0.3231373f, 0.3607844f, 0.3937255f));
            _terrainEffect.Parameters["DirLight2SpecularColor"].SetValue(new Vector3(0.3231373f, 0.3607844f, 0.3937255f));
            _terrainEffect.Parameters["Texture1"].SetValue(Game.Content.Load<Texture2D>("textures\\grass"));            
            _terrainEffect.Parameters["World"].SetValue(Matrix.Identity);
            _terrainEffect.Parameters["Projection"].SetValue(World.ProjMatrix);
            _terrainEffect.Parameters["View"].SetValue(World.ViewMatrix);

            foreach (EffectPass pass in _terrainEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                          World.Terrain.Vertices.Length, 0,
                                                          World.Terrain.Indices.Length/3);
            }

            base.Draw(gameTime);
        }

        #endregion

        #region Private Methods

        private void InitVertexAndIndexBuffers(VertexDeclaration vertexDeclaration)
        {
            _vertexBuffer = new VertexBuffer(Game.GraphicsDevice, vertexDeclaration, World.Terrain.Vertices.Length,
                                             BufferUsage.WriteOnly);
            _vertexBuffer.SetData(World.Terrain.Vertices);

            _indexBuffer = new IndexBuffer(Game.GraphicsDevice, typeof (int), World.Terrain.Indices.Length,
                                           BufferUsage.WriteOnly);
            _indexBuffer.SetData(World.Terrain.Indices);
        }

        #endregion
    }
}
